package cn.com.codes.testCaseLibManager.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.com.codes.common.SecurityContextHolderHelp;
import cn.com.codes.common.util.StringUtils;
import cn.com.codes.framework.app.services.BaseServiceImpl;
import cn.com.codes.object.CaseExeHistory;
import cn.com.codes.object.CaseLibCategory;
import cn.com.codes.object.CaseLibTestCaseInfo;
import cn.com.codes.object.TestCaseInfo;
import cn.com.codes.testCaseLibManager.dto.TestCaseLibManagerDto;
import cn.com.codes.testCaseLibManager.service.TestCaseLibManagerService;

public class TestCaseLibManagerServiceImpl extends BaseServiceImpl implements TestCaseLibManagerService {

	@Override
	public List<CaseLibCategory> loadTree(TestCaseLibManagerDto dto) {
		String companyId = dto.getCompanyId();
		Long currNodeId = dto.getCurrNodeId();
		CaseLibCategory rootOutLine = null;
		if(currNodeId==null){
			String rootNodeIdHql = "select new  CaseLibCategory(categoryId , superId, isleafNode,  categoryName, categoryState, categoryLevel, categoryNum) from CaseLibCategory where companyId=? and superId =0 order by categorySeq asc" ;
			rootOutLine = (CaseLibCategory)this.findByHql(rootNodeIdHql, companyId).get(0);
			currNodeId = rootOutLine.getCategoryId();
		}
		
		String loadTreeHql = this.buildLoadChildHql(false);
		List<CaseLibCategory> list = null;
		if(dto.getIsMoveOpera()){
			list = this.findByHqlWithReshFlg(loadTreeHql,true,currNodeId);
		}else{
			list = this.findByHql(loadTreeHql,currNodeId);
		}
		if(rootOutLine!=null&&list.size()>0){
			list.add(0, rootOutLine);
		}else if(rootOutLine!=null){
			list.add(rootOutLine);
		}
		return list;
	}

	@Override
	public List<CaseLibCategory> loadNormalNode(String companyId, Long currNodeId) {
		
		CaseLibCategory rootOutLine = null;
		if(currNodeId==null){
			String rootNodeIdHql = "select new  CaseLibCategory(categoryId , superId, isleafNode,  categoryName, categoryState, categoryLevel, categoryNum) from CaseLibCategory  where companyId=? and superId =0 order by categorySeq " ;
			if(this.findByHql(rootNodeIdHql, companyId) != null && this.findByHql(rootNodeIdHql, companyId).size() > 0){
				rootOutLine = (CaseLibCategory)this.findByHql(rootNodeIdHql, companyId).get(0);
				currNodeId = rootOutLine.getCategoryId();
			}
		}
		String loadTreeHql = this.buildLoadChildHql(true);
		List<CaseLibCategory> list = this.findByHql(loadTreeHql,currNodeId);
		if(rootOutLine!=null&&list.size()>0){
			list.add(0, rootOutLine);
		}else if(rootOutLine!=null){
			list.add(rootOutLine);
		}
		return list;
	}

	@Override
	public List addNodes(List<CaseLibCategory> list) {
		int isleafNode = 0 ;
		Long parentId = null;
		if(list.size()>0){
			parentId = list.get(0).getSuperId();
			CaseLibCategory parent = super.getHibernateGenericController().load(CaseLibCategory.class, parentId);
			isleafNode = parent.getIsleafNode();
			if(isleafNode==1){
				parent.setIsleafNode(0);
				this.update(parent);				
			}
		}
		for(CaseLibCategory outLine :list){
			this.add(outLine);
		}
		if(parentId!=null && isleafNode ==0){
			String loadTreeHql = this.buildLoadChildHql(false);
			return this.findByHql(loadTreeHql,parentId);
			
		}
		return list;
	}

	private String buildLoadChildHql(boolean onlyNormal){
		StringBuffer sb = new StringBuffer(" from CaseLibCategory  where  superId=? ");
		if(onlyNormal){
			sb.append(" and categoryState!=1 ");
		}
		sb.append(" order by categorySeq ,categoryId");
		return sb.toString();
	}
	
	@Override
	public void updateNode(TestCaseLibManagerDto dto) {
		Long nodeId  = dto.getCurrNodeId();
		String nodeName = dto.getCategoryName();
		String hql="update CaseLibCategory set categoryName=? where categoryId=? and companyId=?";
		super.getHibernateGenericController().executeUpdate(hql, nodeName,nodeId,dto.getCompanyId());

	}

	@Override
	public void switchState(TestCaseLibManagerDto dto) {
		

	}

	@Override
	public void delete(CaseLibCategory caseLibCategory) {
		String hql = "delete from CaseLibCategory where categoryId=? and companyId=? and superId !=0" ;
	
		this.executeUpdateByHql(hql, new Object[]{caseLibCategory.getCategoryId(),caseLibCategory.getCompanyId()});
		this.setParentIsLeaf(caseLibCategory.getSuperId());

	}

	@Override
	public void moveUpItem(TestCaseLibManagerDto dto) {
		
		Long parentId = dto.getParentNodeId();
		Long currNodeID = dto.getCurrNodeId();
		Integer currSeq = dto.getCurrSeq();
		if(this.isTop(currSeq, parentId)){
			return;
		}
		String upHql = "update CaseLibCategory set categorySeq=? where superId=?  and categorySeq =?";
		this.executeUpdateByHql(upHql, new Object[]{currSeq,parentId,currSeq-1});
		String downHql = "update CaseLibCategory set categorySeq=? where categoryId=? ";
		this.executeUpdateByHql(downHql, new Object[]{currSeq-1,currNodeID});	
	}
	
	private boolean isTop(Integer mySeq,Long parentId){
		String sql = "select min(category_seq) from t_case_lib_category where super_id = ?";
		List list = this.findBySql(sql, null, parentId);
		if(list==null||list.isEmpty()||list.get(0)==null){
			return true;
		}
		if(list.get(0).toString().equals(mySeq.toString())){
			return true;
		}
		return false;
		
	}

	@Override
	public void moveDownItem(TestCaseLibManagerDto dto) {
		
		Long parentId = dto.getParentNodeId();
		Long currNodeID = dto.getCurrNodeId();
		Integer currSeq = dto.getCurrSeq();
		if(this.isBottom(currSeq, parentId)){
			return;
		}
		String upHql = "update CaseLibCategory set categorySeq=? where superId=?  and categorySeq =?";
		this.executeUpdateByHql(upHql, new Object[]{currSeq,parentId,currSeq+1});
		String downHql = "update CaseLibCategory set categorySeq=? where categoryId=? ";
		this.executeUpdateByHql(downHql, new Object[]{currSeq+1,currNodeID});
	}

	private boolean isBottom(Integer mySeq,Long parentId){
		String sql = "select max(category_seq) from t_case_lib_category where super_id = ?";
		List list = this.findBySql(sql, null, parentId);
		if(list==null||list.isEmpty()||list.get(0)==null){
			return true;
		}
		if(list.get(0).toString().equals(mySeq.toString())){
			return true;
		}
		return false;
		
	}
	@Override
	public void initSeq(CaseLibCategory caseLibCategory) {
		
		String hql = " from  CaseLibCategory  where superId=?  order by categoryNum ";
		List<CaseLibCategory> list = this.findByHql(hql, caseLibCategory.getSuperId());
		if(list!=null&&!list.isEmpty()){
			int i = 1;
			for(CaseLibCategory node :list){
				node.setCategorySeq(i);
				if(node.getCategoryId().intValue()==caseLibCategory.getCategoryId().intValue()){
					caseLibCategory.setCategorySeq(i);
				}
				this.saveOrUpdate(node);
				i++;
			}
		}
	}

	@Override
	public void move(TestCaseLibManagerDto dto, List<Map<String, Object>> adjustMapInfo) {
		
		Long targetId = dto.getTargetId();
		Long sourceId = dto.getCurrNodeId();
		String hql = "update CaseLibCategory set categorySeq=?, superId=?,categoryLevel=? ,categoryNum=? where categoryId=?" ;
		this.getHibernateGenericController().executeUpdate(hql, dto.getCurrSeq(),targetId,dto.getCurrLevel(),dto.getCategoryNum(),sourceId);
		this.setParentIsLeaf(dto.getParentNodeId());
		hql = "update CaseLibCategory set categoryLevel=:categoryLevel,categoryNum=:categoryNum where categoryId=:categoryId" ;
		this.excuteBatchHql(hql, adjustMapInfo);
		hql="update CaseLibCategory set isleafNode=? where categoryId=?";
		this.getHibernateGenericController().executeUpdate(hql, 0,targetId);
		hql = "update CaseLibTestCaseInfo set categoryNum=:categoryNum where categoryId=:categoryId ";
		this.excuteBatchHql(hql, dto.getHqlParamLists());
		adjustMapInfo = null;
		dto.setHqlParamLists(null);
	}
	
	private void setParentIsLeaf(Long superModuleId){
		String hql = " from CaseLibCategory where superId=?" ;
		int childCount = this.getHibernateGenericController().getResultCount(hql, new Object[]{superModuleId}, "categoryId").intValue();
		if(childCount==0){
			hql="update CaseLibCategory set isleafNode=? where categoryId=?";
			super.getHibernateGenericController().executeUpdate(hql, 1,superModuleId);
		}
	}
	public List loadAuditCase(TestCaseLibManagerDto dto,String categoryNum) {
		this.buildLoadCaseHql(dto, categoryNum,true);
		return this.findByHqlWithValuesMap(dto.getHql(), dto.getPageNo(), dto.getPageSize(), "testCaseId", dto.getHqlParamMaps(), false);
	}
	public List loadCase(TestCaseLibManagerDto dto,String categoryNum){
		this.buildLoadCaseHql(dto, categoryNum,false);
		return this.findByHqlWithValuesMap(dto.getHql(), dto.getPageNo(), dto.getPageSize(), "testCaseId", dto.getHqlParamMaps(), false);
	}
	
	private void buildLoadCaseHql(TestCaseLibManagerDto dto,String categoryNum,boolean isAudit){
		StringBuffer hql = new StringBuffer();
		Map praValuesMap = new HashMap();
		praValuesMap.put("companyId", dto.getCompanyId());


		hql.append(" from CaseLibTestCaseInfo  where companyId=:companyId "); 
		if(!isAudit) {
			hql.append(" and examineStatus=1 "); 
		}else {
			hql.append(" and examineStatus=0 "); 
		}
		if(categoryNum!=null&&!"".equals(categoryNum)){
			hql.append("  and categoryNum like :categoryNum");
			praValuesMap.put("categoryNum", categoryNum+"%");
		}
		if(dto.getTestCase()==null){
			dto.setHqlParamMaps(praValuesMap);
			hql.append(" order by updDate desc");
			dto.setHql(hql.toString());
			return;
		}

		if(!StringUtils.isNullOrEmpty(dto.getTestCase().getBaselineId())){
			hql.append(" and baselineId=:baselineId");
			praValuesMap.put("baselineId", dto.getTestCase().getBaselineId());
		}


		if(dto.getTestCase().getWeight()!=null){
			hql.append(" and weight = :weight");
			praValuesMap.put("weight", dto.getTestCase().getWeight());
		}
		if(dto.getTestCase().getTestCaseDes()!=null&&!"".equals(dto.getTestCase().getTestCaseDes().trim())){
			hql.append(" and testCaseDes like :testCaseDes");
			praValuesMap.put("testCaseDes", "%"+dto.getTestCase().getTestCaseDes().trim()+"%");
		}
		hql.append(" order by updDate desc");
		dto.setHql(hql.toString());
		dto.setHqlParamMaps(praValuesMap);
	}
	
	public int  saveImpotTestCase(List<CaseLibTestCaseInfo> list) {
		int addCount = 0;
		for(CaseLibTestCaseInfo testCase :list){
			if(testCase.getCategoryId()!=null&&testCase.getCaseType()!=null&&testCase.getCasePri()!=null) {
				this.add(testCase);
				addCount++;
			}

		}
		return addCount;
	}
	@Override
	public void saveCase(CaseLibTestCaseInfo caseLibTestCaseInfo){
		this.add(caseLibTestCaseInfo);
	}
	
	@Override
	public void updateCase(CaseLibTestCaseInfo caseLibTestCaseInfo){
		this.update(caseLibTestCaseInfo);
	}
	
	@Override
	public void deleteCase(CaseLibTestCaseInfo caseLibTestCaseInfo){
		this.executeUpdateByHql("delete from CaseLibTestCaseInfo where testCaseId =? ", new Object[]{caseLibTestCaseInfo.getTestCaseId()});
	}
	
	@Override
	public void updateExamineState(CaseLibTestCaseInfo caseLibTestCaseInfo){
		this.executeUpdateByHql("update CaseLibTestCaseInfo set examineStatus = '1',examineUserId = ? where testCaseId =? ", new Object[]{caseLibTestCaseInfo.getExamineUserId(),caseLibTestCaseInfo.getTestCaseId()});
	}
}
